package com.haipumi.webSocket;

import java.util.Hashtable;
import java.util.Map;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import com.haipumi.beans.haipumi_chatInfo;
import com.haipumi.redis.RedisUtil;
import com.haipumi.utils.GetNowTime;
import com.haipumi.utils.GsonUtil;
import com.haipumi.utils.LogUtil;

@ServerEndpoint("/customerServiceWebsocket")
public class CustomerServiceWebsocket {
	private String format="yyyy-MM-dd HH-mm-ss";
	
    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    //用于初次连接时的分配临时ID 
    private static int TEMPID = 0;
     
    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话，可以使用Map来存放，其中Key可以为用户标识
    private static Map<String,CustomerServiceWebsocket > CustomerServiceMap = new Hashtable<String, CustomerServiceWebsocket >();
    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    
    //当前用户的ID
    private String UserId;
    //临时ID标记,因为刚建立连接的时候,并不能得到用户的id
    private String tempId;
    
    private RedisUtil redis;
    /**
     * 连接建立成功调用的方法
     * @param session  可选的参数。session为与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(Session session){
    	this.session = session;
    	tempId=getTEMPID();
        addOnlineCount();           //在线数加1
        LogUtil.log.debug("有新连接加入！当前在线人数为" + getOnlineCount());
        System.out.println("临时Id:  "+tempId);
    }
     
    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage(String message, Session session) {
    	LogUtil.log.debug("临时ID"+tempId+"用户ID"+UserId+"来自客户端的消息:"+message);
    	//传来的消息格式    发送人ID,接收人ID-MESSAGE
    	int textIndex=message.indexOf("-");
    	String UsersId=message.substring(0, textIndex );//获取用户ID的字符串
    	String text=message.substring(textIndex+1);//获取消息的字符串

    	String[] UsersIds=UsersId.split(",");
    	if(UserId==null ){//说明是第一次的登记操作
    		UserId=UsersIds[0];
    		CustomerServiceMap.put(UserId, this);//以用户ID为键
    	}
    	String friendId=UsersIds[1];//对方的Id
    	
    	if(friendId!="0" &&  CustomerServiceMap.containsKey(friendId)) {//取出聊天对方的session,并发送消息
    		CustomerServiceWebsocket customerService=CustomerServiceMap.get(friendId);
    		customerService.session.getAsyncRemote().sendText("{\"fromId\":\""+UserId+"\",\"message\":\""+text+"\"}");
    	}
    	
    	haipumi_chatInfo chatInfo=new haipumi_chatInfo();
    	chatInfo.setCiaccid(friendId);
    	chatInfo.setUid(UsersId);
    	chatInfo.setCicontent(text);
    	chatInfo.setCidatetime(GetNowTime.getNowTime(format));
    	WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
    	RedisUtil sc=(RedisUtil) wac.getBean("redisUtil");
    	sc.setListData("chatInfo"+UsersId, GsonUtil.getJsonString(chatInfo));
//    	System.out.println(UsersId);
//    	System.out.println( sc.getListData("chatInfo"+UsersId, 0, 1).get(0) );
    }
     
    /**
     * 发生错误时调用
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error){
    	removeSession();
        subOnlineCount();           //在线数减1 
    	LogUtil.log.fatal("客服信息传输 发生错误");
        error.printStackTrace();
    }
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(){
    	removeSession();
        subOnlineCount();           //在线数减1    
        LogUtil.log.debug("有一连接关闭！当前在线人数为" + getOnlineCount());
    }
     
    //获取当前在线人数
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
    //人数加1
    public static synchronized void addOnlineCount() {
    	CustomerServiceWebsocket.onlineCount++;
    }
    //人数减1
    public static synchronized void subOnlineCount() {
    	if(CustomerServiceWebsocket.onlineCount>0){
    		CustomerServiceWebsocket.onlineCount--;
    	}
    }

	public static synchronized String getTEMPID() {
		TEMPID++;
		return Integer.toString( TEMPID );
	}
    
	private void removeSession(){
		if(tempId!=null &&CustomerServiceMap.containsKey(tempId)){
			CustomerServiceMap.remove(tempId);  //从set中删除
			tempId=null;
		}
		if(UserId!=null && CustomerServiceMap.containsKey(UserId)){
			CustomerServiceMap.remove(UserId);  //从set中删除
			UserId=null;
		}
	}
	
	public Session getSession() {
		return session;
	}

	/**
     * 这个方法与上面几个方法不一样。没有用注解，是根据自己需要添加的方法。
     * @param message
     * @throws IOException
     */
    public static void pushMessage(String message) {
    	for(Map.Entry<String,CustomerServiceWebsocket> entry:CustomerServiceMap.entrySet()){
    		CustomerServiceWebsocket websocket=entry.getValue();
    		Session session=websocket.getSession();
    		if(session.isOpen()){
    			session.getAsyncRemote().sendText(message);
    		}
    	}
    }
    
//    this.session.getBasicRemote().sendText(message);//阻塞
//    this.session.getAsyncRemote().sendText(message);//非阻塞
//	for (Session sess : session.getOpenSessions()) {
//	   if (sess.isOpen()){
//		   sess.getAsyncRemote().sendText(message);
//	   }
//	}
}